<template>
    <div class="circular-progress-container">
        <div class="circular-progress">
            <svg class="progress-ring" viewBox="0 0 100 100">
                <!-- 背景圆环 (蓝色) -->
                <circle class="progress-ring-bg" cx="50" cy="50" r="45" stroke="#1E90FF" stroke-width="8" fill="none" />
                <!-- 进度圆环 (黄色) -->
                <circle class="progress-ring-fill" cx="50" cy="50" r="45" stroke="#FFD700" stroke-width="20" fill="none"
                    :stroke-dasharray="circumference" :stroke-dashoffset="strokeDashOffset" />
            </svg>
            <div class="progress-text">
                <span class="percentage">{{ progress }}%</span>
            </div>
        </div>
    </div>
</template>

<script setup>
import { computed, ref, watch , onUnmounted  } from 'vue'

const props = defineProps({
    progress: {
        type: Number,
        default: 54, // 默认值设为图片中的54%
        validator: value => value >= 0 && value <= 100
    },
    // 以下是可自定义的颜色参数
    bgColor: {
        type: String,
        default: '#1E90FF' // 蓝色背景环
    },
    progressColor: {
        type: String,
        default: '#FFD700' // 黄色进度环
    },
    textColor: {
        type: String,
        default: '#FFD700' // 黄色百分比文字
    },
    labelColor: {
        type: String,
        default: '#FFFFFF' // 白色标签文字
    },
    // 动画持续时间(毫秒)
    duration: {
        type: Number,
        default: 1500
    },
    width: {
        type: Number,
        default: 100
    },
    height: {
        type: Number,
        default: 100
    }
})

const radius = 45
const circumference = 2 * Math.PI * radius
const animatedProgress = ref(0)
let animationStartTime = null
let animationFrameId = null

// 计算stroke-dashoffset值
const strokeDashOffset = computed(() => {
    return circumference - (animatedProgress.value / 100) * circumference
})

// 动画函数
const animateProgress = (targetProgress) => {
    if (animationFrameId) {
        cancelAnimationFrame(animationFrameId)
    }

    const startProgress = animatedProgress.value
    const progressDelta = targetProgress - startProgress
    animationStartTime = performance.now()

    const animate = (timestamp) => {
        const elapsed = timestamp - animationStartTime
        const progress = Math.min(elapsed / props.duration, 1)
        animatedProgress.value = startProgress + progress * progressDelta

        if (progress < 1) {
            animationFrameId = requestAnimationFrame(animate)
        } else {
            animationFrameId = null
        }
    }

    animationFrameId = requestAnimationFrame(animate)
}

// 监听progress变化触发动画
watch(() => props.progress, (newVal) => {
    animateProgress(newVal)
}, { immediate: true })

// 组件卸载时清除动画
onUnmounted(() => {
    if (animationFrameId) {
        cancelAnimationFrame(animationFrameId)
    }
})
</script>

<style scoped lang="scss">
@import "@/assets/styles/three-home.scss";


.circular-progress-container {
    display: flex;
    justify-content: center;
    align-items: center;
    width: vw(70);
    height: vh(70);
}

.circular-progress {
    position: relative;
    width: 80px;
    height: 80px;
}

.progress-ring {
    width: 100%;
    height: 100%;
    transform: rotate(-90deg);
}

.progress-ring-bg {
    fill: none;
    stroke: v-bind('props.bgColor');
    stroke-width: 8;
}

.progress-ring-fill {
    fill: none;
    stroke: v-bind('props.progressColor');
    stroke-width: 11;
    // stroke-linecap: round;
    transition: stroke-dashoffset 0.5s ease-out;
}

.progress-text {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
}

.percentage {
    display: block;
    font-size: vh(20);
    font-weight: bold;
    color: v-bind('props.textColor');
}

.label {
    display: block;
    font-size: 14px;
    margin-top: 4px;
    color: v-bind('props.labelColor');
}
</style>